import {
  ApiUrl,
  API_LOGIN_OUT_CODE,
  API_SUCCESS_CODE,
  ABNORMAL_CODE
} from '@/config/api.js'

import { isAbnormalNavTo, abnormalPageList } from '@/config'

import { isValidURL } from '@/libs/utils/validate.js'

import { pinia } from '@/store'

import { useUserStore } from '@/store/modules/user'

const store = useUserStore(pinia)

import { getCurRouter } from '@/libs/utils/router'

let isLogin = false

let isSuccessfulNavTo = true

/**
 * url参数组装
 * @param {*} parameter 参数
 * @returns
 */
export function urlAppendParameter(parameter) {
  let result = ''
  for (const key in parameter) {
    result += key + '=' + parameter[key] + '&'
  }
  result = result.substring(0, result.length - 1)
  return result
}

export default async function request(data, baseUrl = ApiUrl) {
  return new Promise(async (resolve, reject) => {
    // 是否传入的是完整的地址
    let isOutLink = isValidURL(data.url)
    // 如果是完整地址则不拼接请求地址 || 拼接地址
    data.url = (isOutLink ? '' : baseUrl) + data.url

    let {
      needLogin = isOutLink || true,
      url,
      params,
      loadingOpt,
      debug = true,
      showToast = true,
      successCode = API_SUCCESS_CODE
    } = data

    // 请求参数拼接
    if (params) {
      url += (url.indexOf('?') !== -1 ? '&' : '?') + urlAppendParameter(params)
    }

    // 是否开启请求loading 自定义load文案
    if (loadingOpt) {
      if (typeof loadingOpt === 'boolean') {
        loadingOpt = {
          title: '加载中...',
          mask: true
        }
      } else if (typeof loadingOpt === 'string') {
        loadingOpt = {
          title: loadingOpt,
          mask: true
        }
      }
      uni.showLoading(loadingOpt)
    }

    if (debug) {
      console.time(data.url)
      console.info(
        `%c 请求链接参数begin: ${data.url}`,
        'color:orange;font-weight:bold'
      )
      console.info(`data：`, data.data)
      console.info(`params：`, params)
      console.info(
        `%c 请求链接参数end------------------------`,
        'color:orange;font-weight:bold'
      )
    }

    let token = needLogin === false ? '' : store.token

    uni.request({
      url,
      data: data.data,
      method: data.method || 'post',
      dataType: data.dataType || 'json',
      timeout: 10000,
      header: Object.assign(
        {
          Authorization: token,
          'X-Request-Token': token
        },
        data.header || {}
      ),
      success(res) {
        if (debug) {
          console.timeEnd(data.url)
          console.info(
            `%c 请求响应结果begin: ${data.url}`,
            'color:green;font-weight:bold'
          )
          console.info(res.data)
          console.info(
            `%c 请求响应结果end------------------------`,
            'color:green;font-weight:bold'
          )
        }

        // 跳转异常页面
        if (
          ABNORMAL_CODE.includes(res.statusCode) &&
          isAbnormalNavTo &&
          isSuccessfulNavTo
        ) {
          isSuccessfulNavTo = false
          setTimeout(() => {
            isSuccessfulNavTo = true
          }, 500)
          let page = getCurRouter()
          if (!abnormalPageList.includes(page.path)) {
            uni.$navTo(5, '/pages/abnormal-page/abnormal-page')
          }
          reject(res.data)
        }

        let code = res.data.code
        let status = res?.data?.status

        if (code === successCode || status === successCode) {
          resolve(res.data)
          return
        } else {
          reject(res.data)

          // 登录过期

          if (API_LOGIN_OUT_CODE.includes(code)) {
            if (!isLogin) {
              store.removeUserInfo()
              isLogin = true
              uni.$emit('needLogin', needLogin)
            }
            return
          }

          let message = res.data.message

          if (message && showToast) {
            let arr = []

            if (typeof showToast !== 'boolean') {
              if (Array.isArray(showToast)) {
                arr = showToast
              } else {
                arr = [showToast]
              }
            }

            if (!arr.includes(code)) {
              setTimeout(() => {
                uni.showToast({
                  title: message,
                  icon: 'none'
                })
              }, 300)
            }
          }
        }
      },
      fail(err) {
        console.log('request fail', err)
        reject(err)
      },
      complete() {
        if (loadingOpt) {
          uni.hideLoading()
        }
      }
    })
  })
}
